/**
 * 字体颜色,背景色,字号,字体,下划线,删除线
 * @file
 * @since 1.2.6.1
 */

/**
 * 字体颜色
 * @command forecolor
 * @method execCommand
 * @param { String } cmd 命令字符串
 * @param { String } value 色值(必须十六进制)
 * @example
 * ```javascript
 * editor.execCommand( 'forecolor', '#000' );
 * ```
 */
/**
 * 返回选区字体颜色
 * @command forecolor
 * @method queryCommandValue
 * @param { String } cmd 命令字符串
 * @return { String } 返回字体颜色
 * @example
 * ```javascript
 * editor.queryCommandValue( 'forecolor' );
 * ```
 */

/**
 * 字体背景颜色
 * @command backcolor
 * @method execCommand
 * @param { String } cmd 命令字符串
 * @param { String } value 色值(必须十六进制)
 * @example
 * ```javascript
 * editor.execCommand( 'backcolor', '#000' );
 * ```
 */
/**
 * 返回选区字体颜色
 * @command backcolor
 * @method queryCommandValue
 * @param { String } cmd 命令字符串
 * @return { String } 返回字体背景颜色
 * @example
 * ```javascript
 * editor.queryCommandValue( 'backcolor' );
 * ```
 */

/**
 * 字体大小
 * @command fontsize
 * @method execCommand
 * @param { String } cmd 命令字符串
 * @param { String } value 字体大小
 * @example
 * ```javascript
 * editor.execCommand( 'fontsize', '14px' );
 * ```
 */
/**
 * 返回选区字体大小
 * @command fontsize
 * @method queryCommandValue
 * @param { String } cmd 命令字符串
 * @return { String } 返回字体大小
 * @example
 * ```javascript
 * editor.queryCommandValue( 'fontsize' );
 * ```
 */

/**
 * 字体样式
 * @command fontfamily
 * @method execCommand
 * @param { String } cmd 命令字符串
 * @param { String } value 字体样式
 * @example
 * ```javascript
 * editor.execCommand( 'fontfamily', '微软雅黑' );
 * ```
 */
/**
 * 返回选区字体样式
 * @command fontfamily
 * @method queryCommandValue
 * @param { String } cmd 命令字符串
 * @return { String } 返回字体样式
 * @example
 * ```javascript
 * editor.queryCommandValue( 'fontfamily' );
 * ```
 */

/**
 * 字体下划线,与删除线互斥
 * @command underline
 * @method execCommand
 * @param { String } cmd 命令字符串
 * @example
 * ```javascript
 * editor.execCommand( 'underline' );
 * ```
 */

/**
 * 字体删除线,与下划线互斥
 * @command strikethrough
 * @method execCommand
 * @param { String } cmd 命令字符串
 * @example
 * ```javascript
 * editor.execCommand( 'strikethrough' );
 * ```
 */

/**
 * 字体边框
 * @command fontborder
 * @method execCommand
 * @param { String } cmd 命令字符串
 * @example
 * ```javascript
 * editor.execCommand( 'fontborder' );
 * ```
 */

UE.plugins["font"] = function () {
    var me = this,
        fonts = {
            forecolor: "color",
            backcolor: "background-color",
            fontsize: "font-size",
            fontfamily: "font-family",
            underline: "text-decoration",
            strikethrough: "text-decoration",
            fontborder: "border"
        },
        lang = me.getLang(),
        needCmd = {underline: 1, strikethrough: 1, fontborder: 1},
        needSetChild = {
            forecolor: "color",
            backcolor: "background-color",
            fontsize: "font-size",
            fontfamily: "font-family"
        };
    me.setOpt({
        fontfamily: [
            {name: "default", val: "default"},
            {name: "songti", val: "宋体,SimSun"},
            {name: "yahei", val: "微软雅黑,Microsoft YaHei"},
            {name: "kaiti", val: "楷体,楷体_GB2312,SimKai"},
            {name: "heiti", val: "黑体,SimHei"},
            {name: "lishu", val: "隶书,SimLi"},
            // { name: "andaleMono", val: "andale mono" },
            {name: "arial", val: "arial,helvetica,sans-serif"},
            // { name: "arialBlack", val: "arial black,avant garde" },
            // { name: "comicSansMs", val: "comic sans ms" },
            // { name: "impact", val: "impact,chicago" },
            {name: "timesNewRoman", val: "times new roman"}
        ],
        fontsize: [10, 11, 12, 14, 16, 18, 20, 24, 36]
    });

    function mergeWithParent(node) {
        var parent;
        while ((parent = node.parentNode)) {
            if (
                parent.tagName == "SPAN" &&
                domUtils.getChildCount(parent, function (child) {
                    return !domUtils.isBookmarkNode(child) && !domUtils.isBr(child);
                }) == 1
            ) {
                parent.style.cssText += node.style.cssText;
                domUtils.remove(node, true);
                node = parent;
            } else {
                break;
            }
        }
    }

    function mergeChild(rng, cmdName, value) {
        if (needSetChild[cmdName]) {
            rng.adjustmentBoundary();
            if (!rng.collapsed && rng.startContainer.nodeType == 1) {
                var start = rng.startContainer.childNodes[rng.startOffset];
                if (start && domUtils.isTagNode(start, "span")) {
                    var bk = rng.createBookmark();
                    utils.each(domUtils.getElementsByTagName(start, "span"), function (
                        span
                    ) {
                        if (!span.parentNode || domUtils.isBookmarkNode(span)) return;
                        if (
                            cmdName == "backcolor" &&
                            domUtils
                                .getComputedStyle(span, "background-color")
                                .toLowerCase() === value
                        ) {
                            return;
                        }
                        domUtils.removeStyle(span, needSetChild[cmdName]);
                        if (span.style.cssText.replace(/^\s+$/, "").length == 0) {
                            domUtils.remove(span, true);
                        }
                    });
                    rng.moveToBookmark(bk);
                }
            }
        }
    }

    function mergesibling(rng, cmdName, value) {
        var collapsed = rng.collapsed,
            bk = rng.createBookmark(),
            common;
        if (collapsed) {
            common = bk.start.parentNode;
            while (dtd.$inline[common.tagName]) {
                common = common.parentNode;
            }
        } else {
            common = domUtils.getCommonAncestor(bk.start, bk.end);
        }
        utils.each(domUtils.getElementsByTagName(common, "span"), function (span) {
            if (!span.parentNode || domUtils.isBookmarkNode(span)) return;
            if (/\s*border\s*:\s*none;?\s*/i.test(span.style.cssText)) {
                if (/^\s*border\s*:\s*none;?\s*$/.test(span.style.cssText)) {
                    domUtils.remove(span, true);
                } else {
                    domUtils.removeStyle(span, "border");
                }
                return;
            }
            if (
                /border/i.test(span.style.cssText) &&
                span.parentNode.tagName == "SPAN" &&
                /border/i.test(span.parentNode.style.cssText)
            ) {
                span.style.cssText = span.style.cssText.replace(
                    /border[^:]*:[^;]+;?/gi,
                    ""
                );
            }
            if (!(cmdName == "fontborder" && value == "none")) {
                var next = span.nextSibling;
                while (next && next.nodeType == 1 && next.tagName == "SPAN") {
                    if (domUtils.isBookmarkNode(next) && cmdName == "fontborder") {
                        span.appendChild(next);
                        next = span.nextSibling;
                        continue;
                    }
                    if (next.style.cssText == span.style.cssText) {
                        domUtils.moveChild(next, span);
                        domUtils.remove(next);
                    }
                    if (span.nextSibling === next) break;
                    next = span.nextSibling;
                }
            }

            mergeWithParent(span);
            if (browser.ie && browser.version > 8) {
                //拷贝父亲们的特别的属性,这里只做背景颜色的处理
                var parent = domUtils.findParent(span, function (n) {
                    return (
                        n.tagName == "SPAN" && /background-color/.test(n.style.cssText)
                    );
                });
                if (parent && !/background-color/.test(span.style.cssText)) {
                    span.style.backgroundColor = parent.style.backgroundColor;
                }
            }
        });
        rng.moveToBookmark(bk);
        mergeChild(rng, cmdName, value);
    }

    me.addInputRule(function (root) {
        utils.each(root.getNodesByTagName("u s del font strike"), function (node) {
            if (node.tagName == "font") {
                var cssStyle = [];
                for (var p in node.attrs) {
                    switch (p) {
                        case "size":
                            cssStyle.push(
                                "font-size:" +
                                ({
                                    "1": "10",
                                    "2": "12",
                                    "3": "16",
                                    "4": "18",
                                    "5": "24",
                                    "6": "32",
                                    "7": "48"
                                }[node.attrs[p]] || node.attrs[p]) +
                                "px"
                            );
                            break;
                        case "color":
                            cssStyle.push("color:" + node.attrs[p]);
                            break;
                        case "face":
                            cssStyle.push("font-family:" + node.attrs[p]);
                            break;
                        case "style":
                            cssStyle.push(node.attrs[p]);
                    }
                }
                node.attrs = {
                    style: cssStyle.join(";")
                };
            } else {
                var val = node.tagName == "u" ? "underline" : "line-through";
                node.attrs = {
                    style: (node.getAttr("style") || "") + "text-decoration:" + val + ";"
                };
            }
            node.tagName = "span";
        });
        //        utils.each(root.getNodesByTagName('span'), function (node) {
        //            var val;
        //            if(val = node.getAttr('class')){
        //                if(/fontstrikethrough/.test(val)){
        //                    node.setStyle('text-decoration','line-through');
        //                    if(node.attrs['class']){
        //                        node.attrs['class'] = node.attrs['class'].replace(/fontstrikethrough/,'');
        //                    }else{
        //                        node.setAttr('class')
        //                    }
        //                }
        //                if(/fontborder/.test(val)){
        //                    node.setStyle('border','1px solid #000');
        //                    if(node.attrs['class']){
        //                        node.attrs['class'] = node.attrs['class'].replace(/fontborder/,'');
        //                    }else{
        //                        node.setAttr('class')
        //                    }
        //                }
        //            }
        //        });
    });
    //    me.addOutputRule(function(root){
    //        utils.each(root.getNodesByTagName('span'), function (node) {
    //            var val;
    //            if(val = node.getStyle('text-decoration')){
    //                if(/line-through/.test(val)){
    //                    if(node.attrs['class']){
    //                        node.attrs['class'] += ' fontstrikethrough';
    //                    }else{
    //                        node.setAttr('class','fontstrikethrough')
    //                    }
    //                }
    //
    //                node.setStyle('text-decoration')
    //            }
    //            if(val = node.getStyle('border')){
    //                if(/1px/.test(val) && /solid/.test(val)){
    //                    if(node.attrs['class']){
    //                        node.attrs['class'] += ' fontborder';
    //
    //                    }else{
    //                        node.setAttr('class','fontborder')
    //                    }
    //                }
    //                node.setStyle('border')
    //
    //            }
    //        });
    //    });
    for (var p in fonts) {
        (function (cmd, style) {
            UE.commands[cmd] = {
                execCommand: function (cmdName, value) {
                    // console.log("execCommand", cmdName, value);
                    value =
                        value ||
                        (this.queryCommandState(cmdName)
                            ? "none"
                            : cmdName === "underline"
                                ? "underline"
                                : cmdName === "fontborder" ? "1px solid #000" : "line-through");
                    var me = this,
                        range = this.selection.getRange(),
                        text;

                    if (value === "default") {
                        if (range.collapsed) {
                            text = me.document.createTextNode("font");
                            range.insertNode(text).select();
                        }
                        me.execCommand("removeFormat", "span,a", style);
                        if (text) {
                            range.setStartBefore(text).collapse(true);
                            domUtils.remove(text);
                        }
                        mergesibling(range, cmdName, value);
                        range.select();
                    } else {
                        if (!range.collapsed) {
                            if (needCmd[cmd] && me.queryCommandValue(cmd)) {
                                me.execCommand("removeFormat", "span,a", style);
                            }
                            range = me.selection.getRange();

                            range.applyInlineStyle("span", {style: style + ":" + value});
                            mergesibling(range, cmdName, value);
                            range.select();
                        } else {
                            var span = domUtils.findParentByTagName(
                                range.startContainer,
                                "span",
                                true
                            );
                            text = me.document.createTextNode("font");
                            if (
                                span &&
                                !span.children.length &&
                                !span[browser.ie ? "innerText" : "textContent"].replace(
                                    fillCharReg,
                                    ""
                                ).length
                            ) {
                                //for ie hack when enter
                                range.insertNode(text);
                                if (needCmd[cmd]) {
                                    range.selectNode(text).select();
                                    me.execCommand("removeFormat", "span,a", style, null);

                                    span = domUtils.findParentByTagName(text, "span", true);
                                    range.setStartBefore(text);
                                }
                                span && (span.style.cssText += ";" + style + ":" + value);
                                range.collapse(true).select();
                            } else {
                                range.insertNode(text);
                                range.selectNode(text).select();
                                span = range.document.createElement("span");

                                if (needCmd[cmd]) {
                                    //a标签内的不处理跳过
                                    if (domUtils.findParentByTagName(text, "a", true)) {
                                        range.setStartBefore(text).setCursor();
                                        domUtils.remove(text);
                                        return;
                                    }
                                    me.execCommand("removeFormat", "span,a", style);
                                }

                                span.style.cssText = style + ":" + value;

                                text.parentNode.insertBefore(span, text);
                                //修复，span套span 但样式不继承的问题
                                if (!browser.ie || (browser.ie && browser.version === 9)) {
                                    var spanParent = span.parentNode;
                                    while (!domUtils.isBlockElm(spanParent)) {
                                        if (spanParent.tagName === "SPAN") {
                                            //opera合并style不会加入";"
                                            span.style.cssText =
                                                spanParent.style.cssText + ";" + span.style.cssText;
                                        }
                                        spanParent = spanParent.parentNode;
                                    }
                                }

                                if (opera) {
                                    setTimeout(function () {
                                        range.setStart(span, 0).collapse(true);
                                        mergesibling(range, cmdName, value);
                                        range.select();
                                    });
                                } else {
                                    range.setStart(span, 0).collapse(true);
                                    mergesibling(range, cmdName, value);
                                    range.select();
                                }

                                //trace:981
                                //domUtils.mergeToParent(span)
                            }
                            domUtils.remove(text);
                        }
                    }
                    return true;
                },
                queryCommandValue: function (cmdName) {
                    var startNode = this.selection.getStart();
                    var styleVal;

                    //trace:946
                    if (cmdName === "underline" || cmdName === "strikethrough") {
                        var tmpNode = startNode,
                            value;
                        while (
                            tmpNode &&
                            !domUtils.isBlockElm(tmpNode) &&
                            !domUtils.isBody(tmpNode)
                            ) {
                            if (tmpNode.nodeType === 1) {
                                value = domUtils.getComputedStyle(tmpNode, style);
                                if (value !== "none") {
                                    return value;
                                }
                            }

                            tmpNode = tmpNode.parentNode;
                        }
                        return "none";
                    } else if (cmdName === "fontborder") {
                        var tmp = startNode,
                            val;
                        while (tmp && dtd.$inline[tmp.tagName]) {
                            if ((val = domUtils.getComputedStyle(tmp, "border"))) {
                                if (/1px/.test(val) && /solid/.test(val)) {
                                    return val;
                                }
                            }
                            tmp = tmp.parentNode;
                        }
                        return "";
                    } else if (cmdName === "FontSize") {
                        styleVal = domUtils.getComputedStyle(startNode, style);
                        tmp = /^([\d\.]+)(\w+)$/.exec(styleVal);

                        if (tmp) {
                            return Math.floor(tmp[1]) + tmp[2];
                        }

                        return styleVal;
                    } else if (cmdName === 'FontFamily') {
                        styleVal = domUtils.getComputedStyle(startNode, style)
                        // 移除左右引号
                        styleVal = styleVal.replace(/['"]/g, '');
                        // 移除字体 宋体, SimSun 转为 宋体,SimSun，否则以下的判断会出错
                        styleVal = styleVal.replace(/\s*,\s*/g, ',');
                        var fontFamily = lang.fontfamily.default;
                        var fontList = me.options["fontfamily"] || [];
                        for (var i = 0; i < fontList.length; i++) {
                            var v = fontList[i];
                            // console.log('FontFamily', styleVal, v.val);
                            if (v.val === styleVal) {
                                fontFamily = styleVal;
                                break;
                            }
                        }
                        // console.log('fontList', fontList);
                        // console.log('FontFamily', styleVal, fontFamily);
                        return fontFamily;
                    }

                    value = domUtils.getComputedStyle(startNode, style);
                    return value;
                },
                queryCommandState: function (cmdName) {
                    if (!needCmd[cmdName]) return 0;
                    var val = this.queryCommandValue(cmdName);
                    if (cmdName === "fontborder") {
                        return /1px/.test(val) && /solid/.test(val);
                    } else {
                        return cmdName === "underline"
                            ? /underline/.test(val)
                            : /line\-through/.test(val);
                    }
                }
            };
        })(p, fonts[p]);
    }
};
